#include "ntc_temp.h"
#include "adc_driver.h"

// -------------------------- NTC参数配置（根据硬件调整） --------------------------
#define REFERENCE_RESISTANCE_OHM  30000   // 303贴片电阻 = 30kΩ
#define NOMINAL_RESISTANCE_OHM    10000   // NTC标称电阻（10kΩ@25℃，按实际型号调整）
#define NOMINAL_TEMPERATURE_C     25        // 标称温度（℃）
#define B_VALUE                   3950      // NTC B值（按实际型号调整）

// ADC阈值（针对NTC在上端的硬件配置）
#define ADC_OPEN_THRESHOLD        1       // 开路阈值（接近0V）
#define ADC_SHORT_THRESHOLD       0X3FE      // 短路阈值（接近Vref）

// 电阻-温度对照表（每5℃一个点，覆盖-40℃至125℃）
// 数据格式：{温度(℃), 对应NTC电阻(Ω)}
// NTC参数：100kΩ（25℃标称电阻），B值3950K
// 温度范围：-40℃ ~ 125℃，步长1℃，电阻值单位：Ω（取整）
// 富温传感热敏电阻参数：11kΩ（25℃标称电阻），B值3950K
// 修正说明：删除电阻值末尾多余的0，确保量级正确（单位：Ω）
// 富温传感热敏电阻（参考特性：B值3950K，标称电阻相关，覆盖宽温域）
// 温度范围：-40℃ ~ 125℃，电阻值基于NTC特性公式与表格趋势计算，单位：Ω
static const struct {
    int8_t temp_c;        // 温度（℃）
    uint32_t resistance_ohm;  // 对应温度的电阻值（Ω）
} ntc_lookup_table[] = {
    {-40, 277200}, {-39, 263600}, {-38, 250100}, {-37, 236800}, {-36, 224000},
    {-35, 211500}, {-34, 199600}, {-33, 188100}, {-32, 177300}, {-31, 167000},
    {-30, 157200}, {-29, 148100}, {-28, 139400}, {-27, 131300}, {-26, 123700},
    {-25, 116000}, {-24, 110000}, {-23, 103700}, {-22, 97900},  {-21, 92500},
    {-20, 87430},  {-19, 82790},  {-18, 78440},  {-17, 74360},  {-16, 70530},
    {-15, 66920},  {-14, 63540},  {-13, 60340},  {-12, 57330},  {-11, 54500},
    {-10, 51820},  {-9, 49280},   {-8, 46890},   {-7, 44620},   {-6, 42480},
    {-5, 40450},   {-4, 38530},   {-3, 36700},   {-2, 34970},   {-1, 33330},
    {0, 31770},    {1, 30250},    {2, 28820},    {3, 27450},    {4, 26160},
    {5, 24940},    {6, 23770},    {7, 22670},    {8, 21620},    {9, 20630},
    {10, 19680},   {11, 18780},   {12, 17930},   {13, 17120},   {14, 16350},
    {15, 15620},   {16, 14930},   {17, 14260},   {18, 13630},   {19, 13040},
    {20, 12470},   {21, 11920},   {22, 11410},   {23, 10910},   {24, 10450},
    {25, 10000},   {26, 9575},    {27, 9170},    {28, 8784},    {29, 8416},
    {30, 8064},    {31, 7730},    {32, 7410},    {33, 7106},    {34, 6815},
    {35, 6538},    {36, 6273},    {37, 6020},    {38, 5778},    {39, 5548},
    {40, 5327},    {41, 5117},    {42, 4915},    {43, 4723},    {44, 4539},
    {45, 4363},    {46, 4195},    {47, 4037},    {48, 3886},    {49, 3742},
    {50, 3605},    {51, 3473},    {52, 3347},    {53, 3226},    {54, 3110},
    {55, 2998},    {56, 2891},    {57, 2788},    {58, 2689},    {59, 2594},
    {60, 2503},    {61, 2416},    {62, 2332},    {63, 2252},    {64, 2175},
    {65, 2101},    {66, 2030},    {67, 1962},    {68, 1897},    {69, 1835},
    {70, 1775},    {71, 1718},    {72, 1663},    {73, 1610},    {74, 1559},
    {75, 1510},    {76, 1463},    {77, 1418},    {78, 1375},    {79, 1333},
    {80, 1294},    {81, 1256},    {82, 1220},    {83, 1185},    {84, 1152},
    {85, 1120},    {86, 1089},    {87, 1060},    {88, 1032},    {89, 1005},
    {90, 979},     {91, 954},     {92, 930},     {93, 907},     {94, 885},
    {95, 864},     {96, 843},     {97, 823},     {98, 804},     {99, 786},
    {100, 768},    {101, 751},    {102, 735},    {103, 719},    {104, 704},
    {105, 689},    {106, 675},    {107, 662},    {108, 649},    {109, 636},
    {110, 624},    {111, 612},    {112, 600},    {113, 589},    {114, 578},
    {115, 567},    {116, 557},    {117, 547},    {118, 537},    {119, 528},
    {120, 519},    {121, 510},    {122, 501},    {123, 493},    {124, 485},
    {125, 477}
};

#define TABLE_SIZE (sizeof(ntc_lookup_table) / sizeof(ntc_lookup_table[0]))

// -------------------------- 内部函数声明 --------------------------
static uint32_t adc_to_resistance(uint16_t adc_value);
static int16_t resistance_to_temperature(uint32_t resistance);

// -------------------------- 对外接口实现 --------------------------
bool ntc_temp_init(void) {
    // 初始化ADC（所有通道共享ADC外设）
    return adc_init();
}
// -------------------------- 内部函数实现 --------------------------
/**
 * @brief 将ADC值转换为NTC电阻值（针对NTC在上端的硬件）
 * 硬件电路：Vref -> NTC -> ADC采样点 -> 参考电阻 -> GND
 * 计算公式：R_ntc = (ADC值 * R_ref) / (ADC满量程 - ADC值)
 */
static uint32_t adc_to_resistance(uint16_t adc_value) {
    if (adc_value >= ADC_RESOLUTION_12BIT) {
        return 0xFFFFFFFF;  // 防止除零
    }
    uint32_t numerator =REFERENCE_RESISTANCE_OHM;
    uint32_t denominator = adc_value;
     numerator= numerator / adc_value;
     denominator = ADC_RESOLUTION_12BIT - adc_value;
     denominator=numerator* denominator;
    return denominator;
}

bool ntc_read_temperature(AdcChannel channel, int16_t *temp_c) {
    uint16_t adc_raw;
    uint16_t vol_mv;
    AdcReadStatus status;
     uint32_t ntc_resistance=0;
    // 参数检查
    if (temp_c == NULL || 
        channel < ADC_CHANNEL_1 || 
        channel > ADC_CHANNEL_4) {
        return false;
    }
    
    // 读取ADC值（NTC在上端时，温度升高，电阻减小，ADC值减小）

    status = adc_read(channel, &adc_raw, &vol_mv);

    if (status != ADC_READ_OK) {
        *temp_c = 0;
        return false;
    }
    
    // 故障检测（针对NTC在上端的特殊处理）
    if (adc_raw <= ADC_OPEN_THRESHOLD) {
        // NTC开路：此时ADC接近Vref，值较大
        *temp_c = NTC_TEMP_OPEN_CIRCUIT;
        return false;
    } else if (adc_raw >= ADC_SHORT_THRESHOLD) {
        // NTC短路：此时ADC接近0V，值较小
        *temp_c = NTC_TEMP_SHORT_CIRCUIT;
        return false;
    }
    
    // ADC值转换为NTC电阻值（针对NTC在上端的公式）
   
     ntc_resistance = adc_to_resistance(adc_raw);
    // 电阻值转换为温度
    *temp_c = resistance_to_temperature(ntc_resistance);
    
    // 温度范围有效性检查
    if (*temp_c < -40 || *temp_c > 125) {
        return false;
    }
    
    return true;
}


/**
 * @brief 将NTC电阻值转换为温度（查表+线性拟合）
 */
static int16_t resistance_to_temperature(uint32_t resistance) {
    // 查找电阻所在的区间
    for (uint8_t i = 0; i < TABLE_SIZE - 1; i++) {
        // 注意：温度升高，NTC电阻减小，表格按温度升序排列
        if (resistance <= ntc_lookup_table[i].resistance_ohm && 
            resistance >= ntc_lookup_table[i+1].resistance_ohm) {
            
            // 找到区间，进行线性拟合
            int16_t t1 = ntc_lookup_table[i].temp_c;
            int16_t t2 = ntc_lookup_table[i+1].temp_c;
            uint32_t r1 = ntc_lookup_table[i].resistance_ohm;
            uint32_t r2 = ntc_lookup_table[i+1].resistance_ohm;
            
            // 计算比例因子
            uint64_t delta_r = r1 - r2;
            uint64_t delta_t = t2 - t1;
            uint64_t r_diff = r1 - resistance;
            
            // 线性插值计算精确温度
            int16_t temp = t1 + (int16_t)((r_diff * delta_t) / delta_r);
            return temp;
        }
    }
    
    // 超出表格范围
    if (resistance > ntc_lookup_table[0].resistance_ohm) {
        return ntc_lookup_table[0].temp_c - 1;  // 低于最低温度
    } else {
        return ntc_lookup_table[TABLE_SIZE-1].temp_c + 1;  // 高于最高温度
    }
}
    


